package com.catazy.wanandroid.common_base.net.download

import com.catazy.wanandroid.common_base.net.ServiceCreators
import com.catazy.wanandroid.common_base.net.download.api.DownloadApiService
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
import java.io.File
import java.io.InputStream

/**
 * 作者: Tao
 * 日期: 2024/5/23
 * 时间: 14:19
 * 描述: 文件下载器
 */
object FileDownloader {
    // 创建下载服务
    private val service = ServiceCreators.create(DownloadApiService::class.java)

    private var url: String = ""
    private var path: String = ""
    private var listener: DownloadListener? = null
    private var downloadLength: Long = 0
    private var contentLength: Long = 0

    /**
     * 创建下载器
     */
    fun create(url: String): FileDownloader {
        FileDownloader.url = url
        return this
    }

    /**
     * 设置下载路径
     */
    fun setPath(path: String): FileDownloader {
        FileDownloader.path = path
        return this
    }

    /**
     * 设置下载监听
     */
    fun setListener(listener: DownloadListener): FileDownloader {
        FileDownloader.listener = listener
        return this
    }

    /**
     * 开始下载
     */
    suspend fun start() = withContext(Dispatchers.IO) {
        kotlin.runCatching {
            listener?.onStart()
            val response = service.downloadFile(url)
            contentLength = response.contentLength()
            val file = File(path)
            write(response.byteStream(), file)
            listener?.onFinish(path, url)
        }.onFailure {

        }
    }

    /**
     * 写入文件
     */
    private fun write(inputStream: InputStream, file: File) {
        file.outputStream().use { output ->
            val buffer = ByteArray(4 * 1024)
            var read: Int
            while (inputStream.read(buffer).also { read = it } != -1) {
                output.write(buffer, 0, read)
                downloadLength += read
                notifyProgress()
            }
            output.flush()
        }

    }

    /**
     * 通知下载进度
     */
    private fun notifyProgress() {
        val progress = ((downloadLength.toFloat() / contentLength.toFloat()) * 100).toInt()
        listener?.onProgress(progress, contentLength.toFloat())
    }
}